package cn.tedu._05weibo.controller;

import cn.tedu._05weibo.common.response.JsonResult;
import cn.tedu._05weibo.common.response.StatusCode;
import cn.tedu._05weibo.mapper.UserMapper;
import cn.tedu._05weibo.pojo.dto.UserLoginDTO;
import cn.tedu._05weibo.pojo.dto.UserRegDTO;
import cn.tedu._05weibo.pojo.entity.User;
import cn.tedu._05weibo.pojo.vo.UserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpSession;
import java.util.Date;

/**常用注解
 * 1.Slf4j注解:日志注解,添加此注解后会创建一个日志对象
 *
 * 2.Api注解:设置控制器类名在Knife4j API文档中的名称
 *   @Api(tags="01.模块名称")
 *
 * 3.ApiOperation注解:添加在控制器方法上，设置控制器方法在Knife4j API文档中的名称;
 *   @ApiOperation(value="方法名称")
 *
 * 4.ApiIgnore注解:添加在参数前，表示Knife4j API文档会忽略此参数;
 *   public int login(@ApiIgnore HttpSession session) {}
 *
 * 5.ApiModelProperty注解: 添加在POJO类属性上,用来对参数进行描述;
 *   参数说明:value指定参数名称,required指定该参数是否必须,example参数指定示例值;
 *   @ApiModelProperty(value="参数描述",required=true,example="示例值")
 *
 * 6.ApiImplicitParam注解: 添加在控制器方法上,对单个参数进行描述
 *   参数说明:name指定参数名,value指定参数描述, required是否必须, dataType指定参数类型;
 *   @ApiImplicitParam(name="参数名",value="参数描述",required=true,dataType="指定参数类型")
 *   public int login(int id){}
 *
 * 7.ApiImplicitParams注解:添加在控制器方法上,对多个参数进行描述
 *   @ApiImplicitParams(value={@ApiImplicitParam(...),@ApiImplicitParam(...)})
 *   public int login(int id,String username){}
 */
@Api(tags = "01.用户模块")
@Slf4j
@RestController
@RequestMapping("/v1/users/")
public class UserController {
    @Autowired
    private UserMapper userMapper;

    /**
     * 1.注册功能
     * RequestBody注解:请求体注解,
     * 1.当客户端传递的数据格式为application/json时,添加此注解
     * 2.转为JSON格式的字符串,并赋值给userRegDTO的属性
     */
    @ApiOperation(value = "注册")
    @PostMapping("reg")
    public JsonResult reg(@RequestBody @Validated UserRegDTO userRegDTO) {
        /*
            1.确定用户名是否被占用[接口方法1:查询语句]
            2.被占用:return 2
            3.未被占用:将用户信息插入数据表[接口方法2:插入语句],return 1
         */
        //soutp + 回车
//        System.out.println("userRegDTO = " + userRegDTO);

        //使用日志方法打印输出
        log.debug("userRegDTO="+userRegDTO);

        //1.确定用户名是否被占用
        UserVO userVO = userMapper.selectByUsername(userRegDTO.getUsername());
        if (userVO != null) {//被占用
            return new JsonResult(StatusCode.USERNAME_ALREADY_EXISTS);
        }
        //2.存入数据表
        User user = new User();
        BeanUtils.copyProperties(userRegDTO, user);
        user.setCreated(new Date());
        userMapper.insertUser(user);
        return JsonResult.ok(); //注册成功
    }

    /**
     * 2.登录功能
     */
    @ApiOperation(value = "登录")
    @PostMapping("login")
    public JsonResult login(@RequestBody UserLoginDTO userLoginDTO, @ApiIgnore HttpSession session) {
        /*
            1.确认用户名是否正确[查询接口-使用注册的查询接口]
            2.用户名错误:return 3
            3.用户名正确:比较密码
                3.1密码正确:return 1
                3.2密码错误:return 2
         */
//        System.out.println("userLoginDTO = " + userLoginDTO);

        log.debug("userLoginDTO"+userLoginDTO);

        UserVO userVO = userMapper.selectByUsername(userLoginDTO.getUsername());
        if (userVO == null) {//用户名错误
            return new JsonResult(StatusCode.USERNAME_ERROR);
        }
        //比较密码
        if (userLoginDTO.getPassword().equals(userVO.getPassword())) {
            //在服务器内存中设置唯一标识:用于回话保持
            //lucy登陆成功,在服务器内存中:{"user":userVO{id,nickname,password}}
            session.setAttribute("user",userVO);
            return JsonResult.ok();
        }
        return new JsonResult(StatusCode.PASSWORD_ERROR);
    }

    /**
     * 3.获取当前用户功能
     */
    @ApiOperation(value = "当前用户")
    @GetMapping("currentUser")
    public JsonResult currentUser(@ApiIgnore HttpSession session){
        //在服务器内存中获取唯一标识
        UserVO userVO = (UserVO)session.getAttribute("user");
        return JsonResult.ok(userVO);
    }

    /**
     * 退出登录功能
     */
    @ApiOperation(value = "退出登录")
    @GetMapping("logout")
    public void logout(@ApiIgnore HttpSession session){
        //在服务器内存中删除唯一标识
        session.removeAttribute("user");
    }
}
